home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / os2tools / aping / cpicinit.c < prev    next >
Text File  |  1992-06-14  |  32KB  |  913 lines

  1. /*****************************************************************************
  2.  *
  3.  *  MODULE NAME : CPICINIT.C
  4.  *
  5.  *  COPYRIGHTS:
  6.  *             This module contains code made available by IBM
  7.  *             Corporation on an AS IS basis.  Any one receiving the
  8.  *             module is considered to be licensed under IBM copyrights
  9.  *             to use the IBM-provided source code in any way he or she
  10.  *             deems fit, including copying it, compiling it, modifying
  11.  *             it, and redistributing it, with or without
  12.  *             modifications.  No license under any IBM patents or
  13.  *             patent applications is to be implied from this copyright
  14.  *             license.
  15.  *
  16.  *             A user of the module should understand that IBM cannot
  17.  *             provide technical support for the module and will not be
  18.  *             responsible for any consequences of use of the program.
  19.  *
  20.  *             Any notices, including this one, are not to be removed
  21.  *             from the module without the prior written consent of
  22.  *             IBM.
  23.  *
  24.  *  AUTHOR:    Peter J. Schwaller
  25.  *             VNET:     PJS at RALVM6           Tie Line: 444-4376
  26.  *             Internet: pjs@ralvm6.vnet.ibm.com     (919) 254-4376
  27.  *
  28.  *  FUNCTION:  Provides procedures to be used in programs to help them set up
  29.  *             all of the partner program information for CPI-C.  All of the
  30.  *             information is stored in a CPICINIT structure.  The
  31.  *             information is stored in the structure using default and set
  32.  *             calls.
  33.  *
  34.  *             The cpicinit_setup_conversation procedure can then be used
  35.  *             to issue the CPI-C calls to setup a conversation_id.
  36.  *             All of the CPI-C calls from CMINIT to just before CMALLC
  37.  *             are issued.  The program should issue CMALLC on its own
  38.  *             so it can control error handling.
  39.  *
  40.  *             By collecting all of the partner program information within
  41.  *             a single object, restarting a conversation that has failed
  42.  *             is made easier, since the information does not have to
  43.  *             be collected or read from a profile again.
  44.  *
  45.  *  AVAILABILITY:
  46.  *             These sample programs and source are also available on
  47.  *             CompuServe through the APPC Information Exchange.  To get
  48.  *             to the APPC forum just type 'GO APPC' from any CompuServe
  49.  *             prompt.  The samples are available in the Sample Programs
  50.  *             library section.  Just search on the keyword CPICPGMS to
  51.  *             find all the samples in this series.
  52.  *
  53.  *             Updates for the sample programs and support for many more
  54.  *             CPI-C platforms will also be made available on CompuServe.
  55.  *
  56.  *  RELATED FILES:
  57.  *             Uses CPICINIT.H
  58.  *
  59.  *****************************************************************************/
  60.  
  61. /*****************************************************************************
  62.  *
  63.  * OVERVIEW OF CPICINIT CALLS
  64.  *
  65.  * cpicinit_new()                     Creates a CPICINIT object.
  66.  *                                    This must be done before any other
  67.  *                                    cpicinit calls can be used.
  68.  *
  69.  * cpicinit_default_tp_name()         These calls set the initial values
  70.  * cpicinit_default_mode_name()       for CPICINIT parameters.  These should
  71.  * cpicinit_default_destination()     all be issued right after the CPICINIT
  72.  * cpicinit_default_sym_dest_name()   object is created.  Usually, these calls
  73.  *                                    should set the values that should be used
  74.  *                                    only if the user does not specify new
  75.  *                                    values.
  76.  *
  77.  * cpicinit_set_tp_name()             These calls also set the values for
  78.  * cpicinit_set_mode_name()           CPICINIT parameters.  These calls should
  79.  * cpicinit_set_destination()         be used to set values from user input
  80.  *                                    or profile values.  These calls should be
  81.  *                                    used after the user has specified values,
  82.  *                                    through command line parameters, program
  83.  *                                    profiles, or interactive input.
  84.  *
  85.  *   Security calls - only available where supported by CPI-C
  86.  * cpicinit_set_userid                Sets the userid for the conversation.
  87.  * cpicinit_set_passwd                Sets the password for the conversation.
  88.  * cpicinit_query_passwd_required     If a userid was set, then a password
  89.  *                                    is required.
  90.  * cpicinit_get_passwd                Let cpicinit prompt the user for a
  91.  *                                    password.
  92.  * cpicinit_set_security_none         Do not use any security on this conv.
  93.  *
  94.  * cpicinit_setup_conversation()      Handles all CMINIT and set calls.
  95.  *                                    Should be used by the calling program
  96.  *                                    instead of CMINIT.  See description
  97.  *                                    of the procedure for more details.
  98.  *
  99.  * cpicinit_destroy()                 Destroys the CPICINIT object.
  100.  *
  101.  * cpicinit_pln_valid()               These are internal calls used by
  102.  * cpicinit_mode_valid()              cpicinit_setup_conversation.
  103.  *
  104.  *****************************************************************************/
  105.  
  106. /* My CPI-C include file */
  107. /* Hides CMC.H differences among platforms */
  108. #include "cpiccmc.h"
  109.  
  110. #include <stdio.h>
  111. #include <stdlib.h>
  112. #include <string.h>
  113.  
  114.  
  115. /* Collection of routines with special ported version for each platform */
  116. #include "cpicport.h"
  117.  
  118. /* CPI-C error handling routines */
  119. #include "cpicerr.h"
  120.  
  121. /* CPI-C initialization routines */
  122. #include "cpicinit.h"
  123.  
  124.  
  125. /******************************************************************************
  126.  *
  127.  *  cpicinit_new
  128.  *
  129.  *  Creates a new CPICINIT object and returns its handle to the caller.
  130.  *  This object handle must be used on all subsequent cpicinit calls.
  131.  *  All internal fields are initialized appropriately.
  132.  *
  133.  *  If memory cannot be allocated for the CPICINIT object, NULL will be
  134.  *  returned as the result of the call.  Otherwise, the return value will
  135.  *  be a pointer to the CPICINIT object.
  136.  *
  137.  *****************************************************************************/
  138. CPICINIT *
  139. cpicinit_new(void)
  140. {
  141.     CPICINIT * cpicinit;
  142.  
  143.     cpicinit = (CPICINIT *) malloc(sizeof(*cpicinit));
  144.     if (cpicinit == NULL) {
  145.         return NULL;
  146.     }
  147.  
  148.     /* Initialize the entire structure to 0's */
  149.     memset(cpicinit,
  150.            0,
  151.            sizeof(*cpicinit));
  152.  
  153.     /* Set the default symbolic destination name to BLANKs. */
  154.     /* This is the "default-default" if nothing else is set. */
  155.     memset(cpicinit -> def_sym_dest_name,
  156.            ' ',
  157.            sizeof(cpicinit->def_sym_dest_name));
  158.  
  159.     /* Indicate that the values have not yet been SET */
  160.     cpicinit -> set_mode_name = NOT_SET;
  161.     cpicinit -> set_destination = NOT_SET;
  162.     cpicinit -> set_tp_name = NOT_SET;
  163.     cpicinit -> set_userid = NOT_SET;
  164.     cpicinit -> set_passwd = NOT_SET;
  165.     cpicinit -> security_none = NOT_SET;
  166.  
  167.     /*
  168.      * This flag is usedby other cpicinit calls to decide whether or not
  169.      * to show errors encountered during processing.
  170.      *
  171.      * If this value is turned off, the cpicinit routines will not produce
  172.      * any output, even in the event of an error.
  173.      */
  174.     cpicinit -> show_error = SET;
  175.  
  176.  
  177.     /* return a pointer to the structure */
  178.     return cpicinit;
  179. }
  180.  
  181. /******************************************************************************
  182.  *
  183.  *  cpicinit_default_sym_dest_name
  184.  *
  185.  *  Sets a symbolic destination name to be used if no call is made to
  186.  *  cpicinit_set_destination().
  187.  *
  188.  *  Returns:
  189.  *    FALSE, if there was no error.
  190.  *    TRUE,  is there was an error.
  191.  *
  192.  *****************************************************************************/
  193. int
  194. cpicinit_default_sym_dest_name( CPICINIT * cpicinit,
  195.                                 char *     def_sym_dest_name)
  196. /*
  197.  * Set the default symbolic destination name to be used if no destination
  198.  * is ever set.
  199.  */
  200. {
  201.     int length;
  202.     int rc;
  203.  
  204.     length = strlen(def_sym_dest_name);
  205.  
  206.     if (length < sizeof(cpicinit->def_sym_dest_name)) {
  207.         rc = FALSE;
  208.         memcpy(cpicinit->def_sym_dest_name,
  209.                def_sym_dest_name,
  210.                length);
  211.         cpicinit->def_sym_dest_name[length] = '\0';
  212.     } else {
  213.         rc = TRUE;
  214.     }
  215.  
  216.     return rc;
  217. }
  218.  
  219. /******************************************************************************
  220.  *
  221.  *  cpicinit_default_tp_name
  222.  *
  223.  *  Sets a symbolic destination name to be used if no call is made to
  224.  *  cpicinit_set_destination().
  225.  *
  226.  *  Returns:
  227.  *    FALSE, if there was no error.
  228.  *    TRUE,  is there was an error.
  229.  *
  230.  *****************************************************************************/
  231. int
  232. cpicinit_default_tp_name(CPICINIT * cpicinit,
  233.                          char *     tp_name)
  234. /* initialize the tp_name */
  235. {
  236.     int length;
  237.     int rc;
  238.  
  239.     length = strlen(tp_name);
  240.  
  241.     if (length < sizeof(cpicinit->tp_name)) {
  242.         rc = FALSE;
  243.         memcpy(cpicinit->tp_name,
  244.                tp_name,
  245.                length);
  246.         cpicinit->tp_name[length] = '\0';
  247.     } else {
  248.         rc = TRUE;
  249.         if (cpicinit -> show_error) {
  250.              fprintf(stderr,
  251.                      "The TP name you specified is too long:\n%s\n",
  252.                      tp_name);
  253.              fprintf(stderr,
  254.                     "The maximum length of a TP name is %u characters.\n",
  255.                     sizeof(cpicinit->tp_name)-1);
  256.              fprintf(stderr,
  257.                      "TP name of %s will be used.\n", cpicinit->tp_name);
  258.         }
  259.     }
  260.  
  261.     return rc;
  262. }
  263.  
  264. /******************************************************************************
  265.  *
  266.  *  cpicinit_default_mode_name
  267.  *
  268.  *  Sets the default mode name to be used if there is no call made to
  269.  *  cpicinit_set_mode_name().
  270.  *
  271.  *  Returns:
  272.  *    FALSE, if there was no error.
  273.  *    TRUE,  is there was an error.
  274.  *
  275.  *****************************************************************************/
  276. int
  277. cpicinit_default_mode_name(CPICINIT * cpicinit,
  278.                            char *     mode_name)
  279. /* initialize the mode name */
  280. {
  281.     int length;
  282.     int rc;
  283.  
  284.     length = strlen(mode_name);
  285.  
  286.     if (length < sizeof(cpicinit->mode_name)) {
  287.         rc = FALSE;
  288.         memcpy(cpicinit->mode_name,
  289.                mode_name,
  290.                length);
  291.         cpicinit->mode_name[length] = '\0';
  292.         strupr(cpicinit->mode_name);
  293.     } else {
  294.         rc = TRUE;
  295.         if (cpicinit -> show_error) {
  296.             fprintf(stderr,
  297.                     "The mode name you specified is too long:\n%s\n",
  298.                     mode_name);
  299.             fprintf(stderr,
  300.                    "The maximum length of a mode name is %u characters.\n",
  301.                    sizeof(cpicinit->mode_name)-1);
  302.             fprintf(stderr,
  303.                    "Mode name of %s will be used.\n", cpicinit->mode_name);
  304.         }
  305.     }
  306.  
  307.     return rc;
  308. }
  309.  
  310. /******************************************************************************
  311.  *
  312.  *  cpicinit_default_destination
  313.  *
  314.  *  Sets the default destination to be used if there is no call made to
  315.  *  cpicinit_set_destination().  The destination can be either a symbolic
  316.  *  destination name or a partner LU name.  See the
  317.  *  cpicinit_setup_conversation() call for details of how the destination
  318.  *  is used to set up a CPI-C conversation.
  319.  *
  320.  *  Returns:
  321.  *    FALSE, if there was no error.
  322.  *    TRUE,  is there was an error.
  323.  *
  324.  *****************************************************************************/
  325. int
  326. cpicinit_default_destination(CPICINIT * cpicinit,
  327.                              char *     destination)
  328. /* initialize the destination */
  329. {
  330.     int length;
  331.     int rc;
  332.  
  333.     length = strlen(destination);
  334.  
  335.     if (length < sizeof(cpicinit->destination)) {
  336.         rc = FALSE;
  337.         memcpy(cpicinit->destination,
  338.                destination,
  339.                length);
  340.         cpicinit->destination[length] = '\0';
  341.     } else {
  342.         rc = TRUE;
  343.         if (cpicinit -> show_error) {
  344.             fprintf(stderr,
  345.                     "The destination you specified is too long:\n%s\n",
  346.                     destination);
  347.             fprintf(stderr,
  348.             "The maximum length of a destination is %u characters.\n",
  349.                 sizeof(cpicinit->destination)-1);
  350.             fprintf(stderr,
  351.                     "Destination %s will be used.\n", cpicinit->destination);
  352.         }
  353.     }
  354.  
  355.     return rc;
  356. }
  357.  
  358. /*
  359.  * The major difference between the default calls above and the set calls
  360.  * below is the setting of a flag in the set calls indicating that the user
  361.  * has specified this value.  This flag is used later as an indication that
  362.  * any value set by the symbolic destination name entries should be
  363.  * overridden.
  364.  */
  365.  
  366.  
  367. /******************************************************************************
  368.  *
  369.  *  cpicinit_set_tp_name
  370.  *
  371.  *  Returns:
  372.  *    FALSE, if there was no error.
  373.  *    TRUE,  is there was an error.
  374.  *
  375.  *****************************************************************************/
  376. int
  377. cpicinit_set_tp_name(CPICINIT * cpicinit,
  378.                      char *     tp_name)
  379. {
  380.     cpicinit->set_tp_name = SET;
  381.     return cpicinit_default_tp_name(cpicinit, tp_name);
  382. }
  383.  
  384. /******************************************************************************
  385.  *
  386.  *  cpicinit_set_mode_name
  387.  *
  388.  *  Returns:
  389.  *    FALSE, if there was no error.
  390.  *    TRUE,  is there was an error.
  391.  *
  392.  *****************************************************************************/
  393. int
  394. cpicinit_set_mode_name(CPICINIT * cpicinit,
  395.                        char *     mode_name)
  396. {
  397.     cpicinit->set_mode_name = SET;
  398.     return cpicinit_default_mode_name(cpicinit, mode_name);
  399. }
  400.  
  401. /******************************************************************************
  402.  *
  403.  *  cpicinit_set_destination
  404.  *
  405.  *  Returns:
  406.  *    FALSE, if there was no error.
  407.  *    TRUE,  is there was an error.
  408.  *
  409.  *****************************************************************************/
  410. int
  411. cpicinit_set_destination(CPICINIT * cpicinit,
  412.                          char *     destination)
  413. {
  414.     cpicinit->set_destination = SET;
  415.     return cpicinit_default_destination(cpicinit, destination);
  416. }
  417.  
  418. /******************************************************************************
  419.  *
  420.  *  cpicinit_set_userid
  421.  *
  422.  *  Sets the userid to be used for security on the conversation.  Issuing
  423.  *  this call implies that the conversation will use security=PROGRAM;
  424.  *  a password will also be required in order to get a conversation.
  425.  *  The password should be set using either the cpicinit_set_passwd() call
  426.  *  or the cpicinit_get_passwd() call.
  427.  *
  428.  *  Returns:
  429.  *    FALSE, if there was no error.
  430.  *    TRUE,  is there was an error.
  431.  *
  432.  *****************************************************************************/
  433. int
  434. cpicinit_set_userid(CPICINIT * cpicinit,
  435.                     char *     userid)
  436. /* initialize the userid */
  437. {
  438.     int length;
  439.     int rc;
  440.  
  441.     length = strlen(userid);
  442.  
  443.     if (length < sizeof(cpicinit->userid)) {
  444.         rc = FALSE;
  445.         memcpy(cpicinit->userid,
  446.                userid,
  447.                length);
  448.         cpicinit->userid[length] = '\0';
  449.         cpicinit->set_userid = SET;
  450.         cpicinit->security_none = NOT_SET;
  451.     } else {
  452.         rc = TRUE;
  453.         if (cpicinit -> show_error) {
  454.             fprintf(stderr,
  455.                     "The userid you specified is too long:\n%s\n",
  456.                     userid);
  457.             fprintf(stderr,
  458.                    "The maximum length of a userid is %u characters.\n",
  459.                    sizeof(cpicinit->userid)-1);
  460.         }
  461.     }
  462.  
  463.  
  464.     return rc;
  465.  
  466. }
  467. /******************************************************************************
  468.  *
  469.  *  cpicinit_query_passwd_required
  470.  *
  471.  *  Can be used by the program to inquire whether a password will be required
  472.  *  to establish a conversation.  This can be used by a program instead of
  473.  *  keeping track itself of whether a userid has been specified.  If a password
  474.  *  is required, the password should be set using either the
  475.  *  cpicinit_set_passwd() call or the cpicinit_get_passwd() call.
  476.  *
  477.  *  Returns:
  478.  *    TRUE   if password is required
  479.  *    FALSE  if no password should be set
  480.  *
  481.  *****************************************************************************/
  482. int
  483. cpicinit_query_passwd_required(CPICINIT * cpicinit)
  484. {
  485.     if (cpicinit->set_userid == SET && cpicinit->set_passwd == NOT_SET) {
  486.         return TRUE;
  487.     } else {
  488.         return FALSE;
  489.     }
  490. }
  491.  
  492.  
  493. /******************************************************************************
  494.  *
  495.  *  cpicinit_set_passwd
  496.  *
  497.  *  Sets the password to be used with security=PROGRAM.  This call should be
  498.  *  used in conjunction with the cpicinit_set_userid() call.
  499.  *
  500.  *  Returns:
  501.  *    FALSE, if there was no error.
  502.  *    TRUE,  is there was an error.
  503.  *
  504.  *****************************************************************************/
  505. int
  506. cpicinit_set_passwd(CPICINIT * cpicinit,
  507.                     char *     passwd)
  508. /* initialize the passwd */
  509. {
  510.     int length;
  511.     int rc;
  512.  
  513.     length = strlen(passwd);
  514.  
  515.     if (length < sizeof(cpicinit->passwd)) {
  516.         rc = FALSE;
  517.         memcpy(cpicinit->passwd,
  518.                passwd,
  519.                length);
  520.         cpicinit->passwd[length] = '\0';
  521.         cpicinit->set_passwd = SET;
  522.         cpicinit->security_none = NOT_SET;
  523.     } else {
  524.         rc = TRUE;
  525.         if (cpicinit -> show_error) {
  526.             fprintf(stderr,
  527.                     "The password you specified is too long:\n%s\n",
  528.                     passwd);
  529.             fprintf(stderr,
  530.                    "The maximum length of a password is %u characters.\n",
  531.                    sizeof(cpicinit->passwd)-1);
  532.         }
  533.     }
  534.  
  535.     return rc;
  536. }
  537.  
  538.  
  539. /******************************************************************************
  540.  *
  541.  *  cpicinit_get_passwd
  542.  *
  543.  *****************************************************************************/
  544. void
  545. cpicinit_get_passwd(CPICINIT * cpicinit)
  546. {
  547.     printf("\nPassword: ");                 /* display the prompt            */
  548.  
  549.     if (!get_passwd(cpicinit->passwd, sizeof(cpicinit->passwd)-1)) {
  550.         cpicinit->set_passwd = SET;
  551.         cpicinit->security_none = NOT_SET;
  552.     }
  553.     return;
  554. }
  555.  
  556. /******************************************************************************
  557.  *
  558.  *  cpicinit_set_security_none
  559.  *
  560.  *****************************************************************************/
  561. void
  562. cpicinit_set_security_none(CPICINIT * cpicinit)
  563. {
  564.     cpicinit->security_none = SET;
  565. }
  566.  
  567.  
  568. /******************************************************************************
  569.  *
  570.  *  cpicinit_setup_conversation
  571.  *
  572.  *  The goal of this procedure is to initialize a CPI-C conversation ID
  573.  *  and make sure that partner destination information is all specified.
  574.  *  This destination information includes partner LU name, mode name,
  575.  *  and TP name.
  576.  *
  577.  *  To be as flexible as possible, the destination parameter can serve
  578.  *  a dual role.  If specified, the destination is first used as the
  579.  *  symbolic destination name.  If this does not produce a valid partner
  580.  *  LU name, another symbolic destination name will be used and the
  581.  *  destination parameter will be used instead as a partner LU name.
  582.  *
  583.  *  AN OVERVIEW OF THE PROCEDURE
  584.  *
  585.  *  If the destination was SET
  586.  *      use destination as a symbolic destination name
  587.  *      If CMINIT failed or there was no partner LU name extracted
  588.  *          use the default symbolic destination name or all blanks
  589.  *          use the destination as a partner LU name
  590.  *
  591.  *****************************************************************************/
  592. int
  593. cpicinit_setup_conversation(CPICINIT *      cpicinit,
  594.                             unsigned char * cm_conv_id,
  595.                             CPICERR *       cpicerr)
  596. {
  597.     CM_INT32 cm_rc = CM_OK;
  598.     CM_INT32 length;
  599.     int      dest_len;
  600.     char sym_dest_name[8];
  601.  
  602.     /* check if a destination was set by the cpicinit_set_destination() call */
  603.     if (cpicinit->set_destination == SET) {
  604.  
  605.         /* check if the destination could be a symbolic destination name     */
  606.         if (((dest_len = strlen(cpicinit->destination)) <
  607.                                                          MAX_SYM_DEST_NAME)) {
  608.             /*
  609.              * Try to use the specified destination as a symbolic
  610.              * destination name.  A symbolic destination name is blank
  611.              * padded and must contain all uppercase characters.
  612.              */
  613.             memset(sym_dest_name,           /* Initialize the sym dest name  */
  614.                    ' ',                     /* to all blanks.                */
  615.                    sizeof(sym_dest_name));
  616.  
  617.             memcpy(sym_dest_name,           /* Copy the destination into the */
  618.                    cpicinit->destination,   /* sym dest name.                */
  619.                    dest_len);
  620.                                             /* place the null terminator     */
  621.             sym_dest_name[MAX_SYM_DEST_NAME - 1] = '\0';
  622.  
  623.             strupr(sym_dest_name);          /* sym dest must be uppercase    */
  624.  
  625.             /*
  626.              * Since we are using the destination as a sym_dest, make sure
  627.              * we don't also use it as a partner LU name.
  628.              */
  629.             cpicinit->set_destination = NOT_SET;
  630.  
  631.             cminit(cm_conv_id,
  632.                    (unsigned char *)sym_dest_name,
  633.                    &cm_rc);
  634.  
  635.         } else {
  636.             /*
  637.              * The destination was too long to be a symbolic destination name.
  638.              */
  639.         }
  640.  
  641.  
  642.  
  643.         if (cm_rc != CM_OK || !cpicinit_pln_valid(cm_conv_id)) {
  644.  
  645.             /*
  646.              * Since the destination was not a sym_dest, we can use it
  647.              * later as a partner LU name.
  648.              */
  649.             cpicinit->set_destination = SET;
  650.  
  651.             /*
  652.              * Try to use the default symbolic destination name.  If
  653.              * configured, this symbolic destination can be used to
  654.              * initialize the partner LU name and mode name entries,
  655.              * or left blank.
  656.              */
  657.             cminit(cm_conv_id,
  658.                    (unsigned char *)cpicinit->def_sym_dest_name,
  659.                    &cm_rc);
  660.  
  661.             if (cm_rc != CM_OK) {
  662.                 /*
  663.                  * Nothing else worked, so let's try the blank symbolic
  664.                  * destination name.  All CPI-C values will be initialized
  665.                  * to non usable values.
  666.                  */
  667.                 cminit(cm_conv_id,
  668.                        (unsigned char *)BLANK_SYM_DEST_NAME,
  669.                        &cm_rc);
  670.                 if (cm_rc != CM_OK) {
  671.                     return cpicerr_handle_rc(cpicerr, MSG_CMINIT, cm_rc);
  672.                 }
  673.  
  674.                 /*
  675.                  * Since the blank symbolic destination name was used,
  676.                  * we must set the partner LU name and mode even if we
  677.                  * use the defaults.
  678.                  */
  679.                 cpicinit->set_destination = cpicinit->set_mode_name = SET;
  680.  
  681.             }
  682.  
  683.         }
  684.  
  685.     } else {
  686.         /*
  687.          * Although no destination was specified, we can try to continue
  688.          * by using the default symbolic destination name.  If this entry
  689.          * is configured with a valid partner LU, we may be able to
  690.          * establish a connection with a partner.
  691.          */
  692.         cminit(cm_conv_id,
  693.                (unsigned char * )cpicinit->def_sym_dest_name,
  694.                &cm_rc);
  695.         if (cm_rc != CM_OK) {
  696.             /*
  697.              * Fill in conversation information for CPI-C error reporting.
  698.              */
  699.             cpicerr_set_conv_id(cpicerr, cm_conv_id);
  700.             return cpicerr_handle_rc(cpicerr, MSG_CMINIT, cm_rc);
  701.         }
  702.     }
  703.  
  704.     /*
  705.      * Fill in conversation information for CPI-C error reporting.
  706.      */
  707.     cpicerr_set_conv_id(cpicerr, cm_conv_id);
  708.  
  709.     if (cpicinit->set_destination == SET) {
  710.         CM_INT32 dest_length;
  711.         dest_length = strlen(cpicinit->destination);
  712.  
  713. #if defined(PLN_COULD_REQUIRE_LOWERCASE)
  714.         /*
  715.          * strupr should only be performed if the partner LU name is
  716.          * a fully qualified name.
  717.          */
  718. #ifdef FAPI
  719.         if ((strchr(cpicinit->destination,'.') != NULL) || (get_machine_mode() == 0)) {
  720.             strupr(cpicinit->destination);
  721.         }
  722. #else
  723.         if (strchr(cpicinit->destination,'.') != NULL) {
  724.             strupr(cpicinit->destination);
  725.         }
  726. #endif
  727. #else
  728.         strupr(cpicinit->destination);
  729. #endif
  730.  
  731.         cmspln(cm_conv_id,                  /* Set partner LU name           */
  732.                (unsigned char *)cpicinit->destination,
  733.                &dest_length,
  734.                &cm_rc);
  735.         if (cm_rc != CM_OK)
  736.             return cpicerr_handle_rc(cpicerr, MSG_CMSPLN, cm_rc);
  737.     }
  738.  
  739.     /*
  740.      * Since there is no way to query the TP name, we will always set it.
  741.      * The default TP name can be overridden on the cpicinit_set_tp_name
  742.      * call.
  743.      */
  744.  
  745.     length = strlen(cpicinit->tp_name);
  746.     cmstpn(cm_conv_id,                      /* Set TP name                   */
  747.            (unsigned char *)cpicinit->tp_name,
  748.            &length,
  749.            &cm_rc);
  750.     if (cm_rc != CM_OK)
  751.         return cpicerr_handle_rc(cpicerr, MSG_CMSTPN, cm_rc);
  752.  
  753.     /*
  754.      * If there was a cpicinit_set_mode_name call made previously or
  755.      * present mode name is not initialized, we need to set the mode
  756.      * name.
  757.      */
  758.     if ((cpicinit->set_mode_name == SET) ||
  759.                                          !cpicinit_mode_valid(cm_conv_id)) {
  760.         length = strlen(cpicinit->mode_name);
  761.         cmsmn(cm_conv_id,                   /* Set mode name                 */
  762.               (unsigned char *)cpicinit->mode_name,
  763.               &length,
  764.               &cm_rc);
  765.         if (cm_rc != CM_OK)
  766.             return cpicerr_handle_rc(cpicerr, MSG_CMSMN, cm_rc);
  767.     }
  768.  
  769. #if defined(SUPPORTS_SETTING_SECURITY)
  770.     /*
  771.      * If there was a cpicinit_set_userid AND cpicinit_set_passwd call made
  772.      * previously, we need to set the security parameters.  The security
  773.      * functions are not available on all CPI-C platforms.
  774.      */
  775.  
  776.     if (cpicinit->security_none == SET) {
  777.         CM_INT32 security_type;
  778.         security_type = XC_SECURITY_NONE;
  779.         xcscst(cm_conv_id,                  /* Set Security Type             */
  780.                &security_type,
  781.                &cm_rc);
  782.         if (cm_rc != CM_OK)
  783.             return cpicerr_handle_rc(cpicerr, MSG_XCSCST, cm_rc);
  784.     } else {
  785.         if ((cpicinit->set_userid == SET) && (cpicinit->set_passwd == SET)) {
  786.             CM_INT32 security_type;
  787.             security_type = XC_SECURITY_PROGRAM;
  788.             xcscst(cm_conv_id,              /* Set Security Type             */
  789.                    &security_type,
  790.                    &cm_rc);
  791.             if (cm_rc != CM_OK)
  792.                 return cpicerr_handle_rc(cpicerr, MSG_XCSCST, cm_rc);
  793.  
  794.             length = strlen(cpicinit->userid);
  795.             xcscsu(cm_conv_id,              /* Set Security Userid           */
  796.                    (unsigned char *)cpicinit->userid,
  797.                    &length,
  798.                    &cm_rc);
  799.             if (cm_rc != CM_OK)
  800.                 return cpicerr_handle_rc(cpicerr, MSG_XCSCSU, cm_rc);
  801.  
  802.             length = strlen(cpicinit->passwd);
  803.             xcscsp(cm_conv_id,              /* Set Security Password         */
  804.                    (unsigned char *)cpicinit->passwd,
  805.                    &length,
  806.                    &cm_rc);
  807.             if (cm_rc != CM_OK)
  808.                 return cpicerr_handle_rc(cpicerr, MSG_XCSCSP, cm_rc);
  809.  
  810.         }
  811.     }
  812.  
  813. #endif
  814.  
  815.     return FALSE;
  816. }
  817.  
  818.  
  819. /******************************************************************************
  820.  *
  821.  *  cpicinit_destroy
  822.  *
  823.  *  This function is the inverse of the cpicinit_new() call.  All memory
  824.  *  allocated by cpicinit_new() is freed.
  825.  *
  826.  *  This function has no return code.
  827.  *
  828.  *****************************************************************************/
  829. void
  830. cpicinit_destroy(CPICINIT * cpicinit)
  831. {
  832.     free(cpicinit);
  833.     return;
  834. }
  835.  
  836. /******************************************************************************
  837.  *
  838.  *  cpicinit_pln_valid
  839.  *
  840.  *  Internal function, used by cpic_setup_conversation().
  841.  *
  842.  *  This function is used after a cminit() call to ensure that there was
  843.  *  a partner LU name configured with the symbolic destination used on
  844.  *  cminit().  If there was no partner LU name configured with the symbolic
  845.  *  destination name, a partner LU name will have to be set with the cmspln()
  846.  *  call.
  847.  *
  848.  *  Returns:
  849.  *    TRUE  if a partner LU name was configured
  850.  *    FALSE is there was no partner LU name configured
  851.  *
  852.  *****************************************************************************/
  853. int
  854. cpicinit_pln_valid(unsigned char * cm_conv_id)
  855. {
  856.     unsigned char  destination[MAX_DESTINATION]; /* variable to store the    */
  857.                                             /* extracted partner LU name     */
  858.     CM_INT32       length = 0;              /* length of partner LU name     */
  859.     CM_RETURN_CODE cm_rc;                   /* CPI-C return code             */
  860.     int            rc;                      /* procedure return code         */
  861.  
  862.     cmepln(cm_conv_id,                      /* extract partner LU name       */
  863.            destination,
  864.            &length,                         /* length of partner LU name     */
  865.            &cm_rc );
  866.  
  867.     if (cm_rc != CM_OK || (length == 1 && destination[0] == ' ')) {
  868.         rc = FALSE;
  869.     } else {
  870.         rc = TRUE;
  871.     }
  872.     return rc;
  873. }
  874.  
  875. /******************************************************************************
  876.  *
  877.  *  cpicinit_mode_valid
  878.  *
  879.  *  Internal function, used by cpic_setup_conversation().
  880.  *
  881.  *  This function is used after a cminit() call to ensure that there was
  882.  *  a mode name configured with the symbolic destination used on  cminit().
  883.  *  If there was no mode name configured with the symbolic destination name,
  884.  *  a partner LU name will have to be set with the cmsmn() call.
  885.  *
  886.  *  Returns:
  887.  *    TRUE  if a mode name was configured
  888.  *    FALSE is there was no mode name configured
  889.  *
  890.  *****************************************************************************/
  891. cpicinit_mode_valid(unsigned char * cm_conv_id)
  892. {
  893.     unsigned char  mode[MAX_MODE_NAME];     /* variable to store the         */
  894.                                             /* extracted mode name           */
  895.     CM_INT32       length = 0;              /* length of mode name           */
  896.     CM_RETURN_CODE cm_rc;                   /* CPI-C return code             */
  897.     int            rc;                      /* procedure return code         */
  898.  
  899.     cmemn(cm_conv_id,                       /* extract mode name             */
  900.           mode,
  901.           &length,
  902.           &cm_rc );
  903.  
  904.     if (cm_rc != CM_OK || length == 0) {
  905.         rc = FALSE;
  906.     } else {
  907.         rc = TRUE;
  908.     }
  909.     return rc;
  910.  
  911. }
  912.  
  913.